{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 朴素贝叶斯法"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 兼容python2和python3\n",
    "from __future__ import print_function\n",
    "\n",
    "import numpy as np\n",
    "import scipy as sp\n",
    "import pandas as pd\n",
    "import sklearn\n",
    "import math\n",
    "import matplotlib.pyplot as plt\n",
    "from collections import Counter\n",
    "%matplotlib inline"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "lambda_ = 0.2\n",
    "x = [2, 'S']\n",
    "\n",
    "X1 = [1,2,3]\n",
    "X2 = ['S', 'M', 'L']\n",
    "Y = [1, -1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "class NaiveBayes:\n",
    "    def __init__(self, lambda_):\n",
    "        self.lambda_ = lambda_\n",
    "        \n",
    "    def fit(self, X, y):\n",
    "        N, M = X.shape\n",
    "        data = np.hstack((X, y.reshape(N, 1)))\n",
    "        \n",
    "        py = {}\n",
    "        pxy = {}\n",
    "        uniquey, countsy = np.unique(y, return_counts=True)\n",
    "        tmp = dict(zip(uniquey, countsy))\n",
    "        for k,v in tmp.items():\n",
    "            py[k] = (v + self.lambda_)/(N + len(uniquey) * self.lambda_)\n",
    "            tmp_data = data[data[:, -1] == k]\n",
    "            for col in range(M):\n",
    "                uniquecol, countscol = np.unique(tmp_data[:,col], return_counts=True)\n",
    "                tmp1 = dict(zip(uniquecol, countscol))\n",
    "                for kk, vv in tmp1.items():\n",
    "                    pxy['X({})={}|Y={}'.format(col+1, kk, k)] = (vv + self.lambda_)/(v + len(uniquecol) * self.lambda_)\n",
    "                    \n",
    "        self.py = py\n",
    "        self.pxy = pxy\n",
    "\n",
    "        #return self.py, self.pxy\n",
    "    \n",
    "    def predict(self, x):\n",
    "        M = len(x)\n",
    "        res = {}\n",
    "        for k,v in self.py.items():\n",
    "            p = v\n",
    "            for i in range(len(x)):\n",
    "                p = p * self.pxy['X({})={}|Y={}'.format(i+1, x[i], k)]\n",
    "            res[k] = p\n",
    "        print(res)\n",
    "        maxp = -1\n",
    "        maxk = -1\n",
    "        for kk,vv in res.items():\n",
    "            if vv > maxp:\n",
    "                maxp = vv\n",
    "                maxk = kk\n",
    "                \n",
    "        return maxk"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "lambda_ = 0.2\n",
    "d = {'S':0, 'M':1, 'L':2}\n",
    "\n",
    "X = np.array([[1, d['S']], [1, d['M']], [1, d['M']],\n",
    "             [1, d['S']], [1, d['S']], [2, d['S']],\n",
    "             [2, d['M']], [2, d['M']], [2, d['L']],\n",
    "             [2, d['L']], [3, d['L']], [3, d['M']],\n",
    "             [3, d['M']], [3, d['L']], [3, d['L']]])\n",
    "\n",
    "y = np.array([-1, -1, 1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, -1])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(array([[1, 0],\n",
       "        [1, 1],\n",
       "        [1, 1],\n",
       "        [1, 0],\n",
       "        [1, 0],\n",
       "        [2, 0],\n",
       "        [2, 1],\n",
       "        [2, 1],\n",
       "        [2, 2],\n",
       "        [2, 2],\n",
       "        [3, 2],\n",
       "        [3, 1],\n",
       "        [3, 1],\n",
       "        [3, 2],\n",
       "        [3, 2]]),\n",
       " array([-1, -1,  1,  1, -1, -1, -1,  1,  1,  1,  1,  1,  1,  1, -1]))"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X, y"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{-1: 0.06506624688442873, 1: 0.024891774891774892}\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "-1"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "model = NaiveBayes(lambda_)\n",
    "model.fit(X,y)\n",
    "model.predict(np.array([2, 0]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
